package com.javaee.wordtree.service;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.javaee.wordtree.entity.DateRecord;
import com.javaee.wordtree.entity.MmryRecord;
import com.javaee.wordtree.entity.Word;
import com.javaee.wordtree.mapper.DateRecordMapper;
import com.javaee.wordtree.mapper.MmryRecordMapper;
import com.javaee.wordtree.mapper.WordMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.*;


@Service
@Slf4j
public class MemoryService {

    @Resource
    private WordMapper wordMapper;

    @Resource
    private MmryRecordMapper mmryRecordMapper;

    @Resource
    private DateRecordMapper dateRecordMapper;

    //艾宾浩斯遗忘曲线记忆周期
    private int[] memoryCircle = {1,2,4,7,15};

    /**
     * 获取目标词书中新的未学习单词
     */
    public List<Word> getNewWords(String userID,int needCount){

        Map<String,Object> map = new HashMap<String, Object>();
        map.put("userID",userID);
        map.put("needCount",needCount);
        List<Integer> newWordsID = wordMapper.findNewWordsID(map);
        List<Word> newWords = new ArrayList<>(needCount);
        for(Integer i : newWordsID){
            Word targetWord = wordMapper.findWord(i);
            newWords.add(targetWord);
        }
        return newWords;
    }

    /**
     *获取今日应复习的单词
     */
    public List<Word> getNeedReviewWords(String userID){
        int needReviewWordCount = mmryRecordMapper.findNeedReviewWordCount(userID);
        List<Integer> reviewWordsID = mmryRecordMapper.findNeedReviewWordsID(userID);
        List<Word> reviewWords = new ArrayList<>(needReviewWordCount);
        for(Integer i : reviewWordsID){
            Word targetWord = wordMapper.findWord(i);
            reviewWords.add(targetWord);
        }
        return reviewWords;
    }

    /**
     * 用户完成一个新单词学习，memory_record表新增1条记录,修改date_record表中的数据
     * @param userID
     * @param wordID
     */
    @Transactional(rollbackFor = Exception.class)
    public void learnNewWord(String userID, int wordID) {
        Date todayDate = DateUtil.beginOfDay(new Date());

        // 1. 先检查是否已有记忆记录
        MmryRecord existingRecord = mmryRecordMapper.selectOne(
                new LambdaQueryWrapper<MmryRecord>()
                        .eq(MmryRecord::getUserID, userID)
                        .eq(MmryRecord::getWordID, wordID)
        );

        // 2. 处理记忆记录（存在则更新，不存在则插入）
        if (existingRecord != null) {
            // 更新现有记录
            existingRecord.setPhase(1);
            existingRecord.setStrange(3);
            existingRecord.setMmryTime(todayDate);
            existingRecord.setNextMmryTime(DateUtil.offsetDay(todayDate, memoryCircle[0]));
            mmryRecordMapper.updateById(existingRecord);
        } else {
            // 插入新记录
            MmryRecord newMmryRecord = new MmryRecord();
            newMmryRecord.setUserID(userID);
            newMmryRecord.setWordID(wordID);
            newMmryRecord.setPhase(1);
            newMmryRecord.setStrange(3);
            newMmryRecord.setMmryTime(todayDate);
            newMmryRecord.setNextMmryTime(DateUtil.offsetDay(todayDate, memoryCircle[0]));
            mmryRecordMapper.insert(newMmryRecord);
        }

        // 3. 处理当天的学习记录（保持不变）
        try {
            LambdaQueryWrapper<DateRecord> lambdaQueryWrapper = Wrappers.lambdaQuery();
            DateRecord dateRecord = dateRecordMapper.selectOne(
                    lambdaQueryWrapper.eq(DateRecord::getUserID, userID)
                            .eq(DateRecord::getDate, todayDate));

            if (dateRecord == null) {
                DateRecord newDateRecord = new DateRecord();
                newDateRecord.setUserID(userID);
                newDateRecord.setDate(todayDate);
                newDateRecord.setLearningTime(1);
                newDateRecord.setLearnCount(1);
                newDateRecord.setReviewCount(0);
                dateRecordMapper.insert(newDateRecord);
            } else {
                dateRecord.setLearnCount(dateRecord.getLearnCount() + 1);
                dateRecordMapper.update(dateRecord,
                        lambdaQueryWrapper.eq(DateRecord::getUserID, userID)
                                .eq(DateRecord::getDate, todayDate));
            }
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw e;
        }
    }

    /**
     * 用户完成一个单词的复习，memory_record更新1条记录
     * @param userID
     * @param wordID
     */
    @Transactional(rollbackFor = Exception.class)
    public void reviewOldWord(String userID, int wordID) {
        Date todayDate = DateUtil.parseDate(DateUtil.today());
        log.info("用户ID："+userID+"单词ID："+wordID);

        try {
            // 1. 查询并更新单词记忆阶段
            LambdaQueryWrapper<MmryRecord> lambdaQueryWrapper = Wrappers.lambdaQuery();
            MmryRecord mmryRecord = mmryRecordMapper.selectOne(
                    lambdaQueryWrapper.eq(MmryRecord::getUserID, userID)
                            .eq(MmryRecord::getWordID, wordID)
            );

            // 更新 strange（生疏度），确保不小于 0
            int currentStrange = mmryRecord.getStrange();
            log.info("currentStrange"+currentStrange);
            mmryRecord.setStrange(Math.max(currentStrange - 1, 0)); // 减1，最低为0

            int index = mmryRecord.getPhase();

            // 当strange为0 或者 phase >=5 时，设置下次记忆时间为15天后
            if (mmryRecord.getStrange() == 0 || index >= 5) {
                Date nextMmryTime = DateUtil.offsetDay(todayDate, 15);
                mmryRecord.setNextMmryTime(nextMmryTime);
                mmryRecord.setPhase(mmryRecord.getPhase() + 1);
            }
            // 否则按照原来的记忆曲线设置
            else if (index < 5) {
                Date nextMmryTime = DateUtil.offsetDay(todayDate, memoryCircle[index]);
                mmryRecord.setNextMmryTime(nextMmryTime);
                mmryRecord.setPhase(mmryRecord.getPhase() + 1);
            }

            // 更新 MmryRecord
            mmryRecordMapper.update(
                    mmryRecord,
                    lambdaQueryWrapper.eq(MmryRecord::getUserID, userID)
                            .eq(MmryRecord::getWordID, wordID)
            );

            // 2. 更新当日学习记录（保持不变）
            LambdaQueryWrapper<DateRecord> dateRecordWrapper = Wrappers.lambdaQuery();
            DateRecord dateRecord = dateRecordMapper.selectOne(
                    dateRecordWrapper.eq(DateRecord::getUserID, userID)
                            .eq(DateRecord::getDate, todayDate)
            );

            if (dateRecord == null) {
                // 如果当天没有学习记录，则新增学习记录
                DateRecord newDateRecord = new DateRecord();
                newDateRecord.setUserID(userID);
                newDateRecord.setDate(todayDate);
                newDateRecord.setLearningTime(1);
                newDateRecord.setLearnCount(0);
                newDateRecord.setReviewCount(1);
                dateRecordMapper.insert(newDateRecord);
            } else {
                // 当天有学习记录则将已复习单词数+1
                dateRecord.setReviewCount(dateRecord.getReviewCount() + 1);
                dateRecordMapper.update(
                        dateRecord,
                        dateRecordWrapper.eq(DateRecord::getUserID, userID)
                                .eq(DateRecord::getDate, todayDate)
                );
            }
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw e; // 可选择重新抛出异常，让调用方感知错误
        }
    }

    /**
     * 更新用户今日学习时长
     * @param userID
     * @param learningTime
     */
    public void updateTodayLearningTime(String userID, int learningTime) {
        // 获取今天的日期（不带时间）
        Date todayDate = DateUtil.parseDate(DateUtil.today());

        // 构造查询条件：userID 和 date 都匹配
        LambdaQueryWrapper<DateRecord> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(DateRecord::getUserID, userID)
                .eq(DateRecord::getDate, todayDate);

        // 查询今天的记录
        DateRecord dateRecord = dateRecordMapper.selectOne(lambdaQueryWrapper);

        if (dateRecord != null) {
            // 如果有记录，就累加学习时间
            dateRecord.setLearningTime(dateRecord.getLearningTime() + learningTime);
            dateRecordMapper.update(dateRecord, lambdaQueryWrapper);
        } else {
            // 没有记录，就插入新记录
            DateRecord newRecord = new DateRecord();
            newRecord.setUserID(userID);
            newRecord.setDate(todayDate);
            newRecord.setLearningTime(learningTime);
            dateRecordMapper.insert(newRecord);
        }
    }

    /**
     * 获取用户今天背的单词
     */
    public List<Word> getTodayLearnedWords(String userID){
        List<Integer> learnedWordsID = mmryRecordMapper.findTodayLearnedWordsID(userID);
        List<Word> learnedWords = new ArrayList<>(learnedWordsID.size());
        for(Integer id : learnedWordsID){
            Word targetWord = wordMapper.findWord(id);
            learnedWords.add(targetWord);
        }
        return learnedWords;
    }



}
